from django.db.models.query import QuerySet
from django.db.models import Model
from django.core import serializers

from django.http import HttpResponse

from django.utils import simplejson
from assets import simplexml

from django.conf import settings
def Serialize(request, data, fields=None):
  formats = {'xml1': 'application/xml', 'json1': 'application/json',}
  format = request.GET.get('format', 'json')
  indent = 2 if settings.DEBUG else None
  if isinstance(data, QuerySet):
    data = serializers.serialize(format, data, fields=fields, indent=indent, use_natural_keys=True)
  elif type(data) == type([]) and len(data) > 0 and isinstance(data[0], Model):
    data = serializers.serialize(format, data, fields=fields, indent=indent, use_natural_keys=True)
  elif isinstance(data, Model):
    data = serializers.serialize(format, data.__class__.objects.filter(id=data.id), fields=fields, indent=indent, use_natural_keys=True)
  else:
    if format == 'json':
      data = simplejson.dumps(data, indent=indent)
    elif format == 'xml':
      data = simplexml.dumps(data, indent=indent)
    else:
      raise Exception('Can\'t serialize type list with formats other then "json"!')

  return data, formats.get(format, 'text/plain')
  
def HttpResponseSerialized(request, data, fields=None):
  data, mime = Serialize(request, data, fields)
  response = HttpResponse(data, mimetype=mime)
  response['Access-Control-Allow-Origin'] = '*'
  return response

def Fields(object, *fields):
  data = {}
  for f in fields:
    if hasattr(object, f):
      data[f] = getattr(object, f)
  return data
  
  
import re
import inspect
def get_services():
  class Service:
    argument_pattern = re.compile(r"\(\?P<\w+>(.*?)\)")
    url_cleaner = re.compile(r"\(\?P<(\w+)>.*?\)")
    def __init__(self, entry, parent):
      self.entry = entry
      self.parent = parent
      
      print dir(self.entry)

      src = inspect.getsource(self.callback)
      def DocumentRequestMethod(method):
        if not hasattr(self.callback, '__doc__'+method+'__'):
          
          pattern = re.compile(r"request\."+method+"\.get\(['\"](.*?)['\"](, ['\"]?(.*?)['\"]?)?\)")
          params = pattern.findall(src)
          if len(params):
            setattr(self.callback, '__doc__'+method+'__', {})
            for p in params:
              getattr(self.callback, '__doc__'+method+'__')[p[0]] = '"'+p[2]+'"' if len(p)==3 else 'Exception'
          
      DocumentRequestMethod('GET')
      DocumentRequestMethod('POST')
      
    @property
    def callback(self):
      return self.entry.callback
      
    @property
    def module(self):
      return getattr(self.entry, '_callback_str', self.callback.__name__)
    @property
    def doc(self):
      return str(self.callback.__doc__).lstrip(' \t\n\r').replace('\\n', '<br/>').replace('\n', '<br/>') if self.callback.__doc__ else ''
    @property
    def url(self):
      u = (self.parent if self.parent else '^') + self.entry.regex.pattern[1:]
      return Service.url_cleaner.sub(r'[\1]', u)
    @property
    def section(self):
      return self.url[1:self.url.find('/')]
    @property 
    def has_arguments(self):
      return len(self.entry.regex.groupindex) > 0
    @property
    def arguments(self):
      patterns = Service.argument_pattern.findall(self.entry.regex.pattern)
      for a, i in self.entry.regex.groupindex.items():
        yield str(a), str(patterns[i-1])
    @property
    def parameter_types(self):
      for method in ['GET', 'POST']:
        if hasattr(self.callback, '__doc__'+method+'__'):  
          print method, getattr(self.callback, '__doc__'+method+'__')
          yield method, getattr(self.callback, '__doc__'+method+'__')
    
  import urls as urls1
  import jobs.urls as urls2
  services = []
  def show_urls(urllist, depth=0, parent=None):
    for entry in urllist:
      if hasattr(entry, 'url_patterns'):
        show_urls(entry.url_patterns, depth + 1, entry.regex.pattern)
      else:
        services.append(Service(entry, parent))
  #TODO: explore installed apps for urls or use 'damweb/urls.py' as root of all
  show_urls(urls1.urlpatterns, parent='^api/')  
  show_urls(urls2.urlpatterns, parent='^jobs/')
  return services



 
